/*
 *  Лицензия MIT
 * 
 *  Copyright 2011 Salnikov Aleksey.
 * 
 *  Данная лицензия разрешает, безвозмездно, лицам, получившим копию данного программного обеспечения
 *  и сопутствующей документации (в дальнейшем именуемыми "Программное Обеспечение"),
 *  использовать Программное Обеспечение без ограничений, включая неограниченное право
 *  на использование, копирование, изменение, объединение, публикацию, распространение,
 *  сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам,
 *  которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:
 * 
 *  Вышеупомянутый копирайт и данные условия должны быть включены во все копии или значимые
 *  части данного Программного Обеспечения.
 * 
 *  ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ ЛЮБОГО ВИДА ГАРАНТИЙ,
 *  ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ,
 *  СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И НЕНАРУШЕНИЯ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ
 *  НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ
 *  ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ
 *  С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
 *  ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
 */

package look.elements;

import CommonTools.Actions;
import CommonTools.Admin;
import CommonTools.AdminComboBoxModel;
import CommonTools.Constants;
import CommonTools.Demand;
import CommonTools.DesignTools;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 *
 * Класс панели с подробной информацией о проблеме
 * @author Salnikov Aleksey
 */
public class DemandPanel extends JPanel{

    protected JTextField themeF, dateStartF, dateEndF, pcF, adminF, userF;
    protected JComboBox adminCmb, statusCmb;
    protected JTextArea subjectF, commentF;
    protected JLabel themeL, dateStartL, dateEndL, pcL, adminL, subjectL, commentL, userL, statusL;
    protected JCheckBox execCB;
    protected JButton execB, saveB;
    private   Demand demand;
    private   JTable table;
    private   Admin iAdmin;
    private   LeftDemandPanel ldp;

    public DemandPanel(Admin iAdmin)
    {
        this.iAdmin = iAdmin;
        /******************************************
         * Инициализируем и настраиваем компоненты
         *****************************************/
        themeF = new JTextField();
        themeF.setEditable(false);

        dateStartF = new JTextField();
        dateStartF.setEditable(false);

        dateEndF = new JTextField();
        dateEndF.setEditable(false);

        pcF = new JTextField();
        pcF.setEditable(false);

        userF = new JTextField();
        userF.setEditable(false);

        adminF = new JTextField();
        adminCmb = new JComboBox();
        
        dateStartF.setEditable(false);

        subjectF = new JTextArea();
        subjectF.setEditable(false);
        subjectF.setLineWrap(true);
        subjectF.setWrapStyleWord(true);
        JScrollPane subjectSP = new JScrollPane(subjectF);

        commentF = new JTextArea();
        //commentF.setEditable(false);
        commentF.setLineWrap(true);
        commentF.setWrapStyleWord(true);
        JScrollPane commentSP = new JScrollPane(commentF);

        execCB = new JCheckBox("Выполнена");

        themeL = new JLabel("Проблема:");
        dateStartL = new JLabel("Поступила:");
        dateEndL = new JLabel("Выполнена:");
        pcL = new JLabel("Компьютер:");
        adminL = new JLabel("Ответственный:");
        subjectL = new JLabel("Описание:");
        commentL = new JLabel("Комментарии:");
        userL = new JLabel("Пользователь:");
        statusL = new JLabel("Статус:");

        adminCmb = new JComboBox();
        try
        {
            Actions.refreshAdminComboBox(adminCmb, true);
        }
        catch (Exception e)
        {
            adminCmb.setSelectedIndex(adminCmb.getModel().getSize() - 1);
        }
        if (!iAdmin.isRoot())
        {
            adminCmb.setEnabled(false);
            //System.out.println(adminCmb.isEditable());
        }

        statusCmb = new JComboBox();
        statusCmb.addItem("Не рассмотрена");
        statusCmb.addItem("В работе");
        statusCmb.addItem("Выполнена");
        statusCmb.addItem("Заблокирована");

        execB = new JButton("Заявка выполнена");
        saveB = new JButton("Сохранить");

        /*************************************************
         * Размещаем компоненты
         ************************************************/
        GridBagLayout gbl = new GridBagLayout();
        gbl.columnWeights = new double [] {0.0,0.5,0.0,0.5, Double.MIN_VALUE};
        gbl.rowWeights = new double [] {0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, Double.MIN_VALUE};
        this.setLayout(gbl);
        GridBagConstraints gbc = new GridBagConstraints();

        Insets leftInsetsLabel = new Insets(3, 10, 0, 20);
        Insets rightInsetsField = new Insets(0,0,0,10);

        gbc.anchor = GridBagConstraints.NORTHWEST;
        //gbc.weighty = 0.5;

        //Размещаем тему
        gbc.fill = gbc.NONE;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(13,10,0,5);
        this.add(themeL, gbc);

        gbc.gridx = 1;
        gbc.gridwidth = 5;
        gbc.fill = gbc.HORIZONTAL;
        gbc.insets = new Insets(10,0,0,10);
        this.add(themeF, gbc);

        //Добавляем компьютер
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        gbc.fill = gbc.NONE;
        gbc.insets = leftInsetsLabel;
        this.add(pcL, gbc);

        gbc.gridx = 1;
        //gbc.gridwidth = 4;
        gbc.fill = gbc.HORIZONTAL;
        gbc.insets = new Insets(0,0,0,5);
        this.add(pcF, gbc);

        //Пользователь
        gbc.gridx = 2;
        gbc.fill = gbc.NONE;
        gbc.insets = new Insets(4,5,0,5);
        this.add(userL, gbc);

        gbc.gridx = 3;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = rightInsetsField;
        this.add(userF, gbc);

        //Размещаем поступление, выполнение, админа
        //Поступление заявки
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 1;
        gbc.fill = gbc.NONE;
        gbc.insets = leftInsetsLabel;
        this.add(dateStartL, gbc);

        gbc.gridx = 1;
        gbc.fill = gbc.HORIZONTAL;
        gbc.insets = new Insets(0,0,0,5);
        this.add(dateStartF, gbc);

        //Выполнение заявки
        gbc.gridx = 2;
        gbc.fill = gbc.NONE;
        gbc.insets = new Insets(4,5,0,5);
        this.add(dateEndL, gbc);

        gbc.gridx = 3;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = rightInsetsField;
        this.add(dateEndF, gbc);

        //Статус заявки
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.fill = gbc.NONE;
        gbc.insets = leftInsetsLabel;
        gbc.gridwidth = 1;
        this.add(statusL, gbc);

        gbc.gridx = 1;
        gbc.fill = gbc.HORIZONTAL;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(0,0,0,5);
        this.add(statusCmb, gbc);

        //Администратор
        gbc.gridx = 2;
        //gbc.gridy = 4;
        gbc.fill = gbc.NONE;
        gbc.insets = new Insets(4,5,0,5);
        gbc.gridwidth = 1;
        this.add(adminL, gbc);

        gbc.gridx = 3;
        gbc.fill = gbc.HORIZONTAL;
        gbc.gridwidth = 4;
        gbc.insets = rightInsetsField;
        this.add(adminCmb, gbc);

        //Добавляем основное
        gbc.gridy = 4;
        gbc.gridx = 0;
        gbc.fill = GridBagConstraints.NONE;
        gbc.insets = leftInsetsLabel;
        gbc.gridwidth = 1;
        this.add(subjectL, gbc);

        gbc.gridx = 1;
        gbc.gridwidth = 4;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = rightInsetsField;
        this.add(subjectSP, gbc);

        //Добавляем комментарии
        gbc.fill = GridBagConstraints.NONE;
        gbc.gridy = 5;
        gbc.gridx = 0;
        gbc.insets = leftInsetsLabel;
        gbc.gridwidth = 1;
        this.add(commentL, gbc);

        gbc.gridx = 1;
        gbc.gridwidth = 4;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(0,0,0,10);
        this.add(commentSP, gbc);

        //Добавляем кнопки
        gbc.gridy = 6;
        gbc.gridwidth = 5;
        gbc.insets = new Insets(0,0,10,8);

        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.add(saveB);
        buttonPanel.add(execB);

        this.add(buttonPanel, gbc);
        commentF.setForeground(Constants.NORMAL_COLOR);

        /*****************************************************
         * Привязваем события
         ****************************************************/
        saveB.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e) {
                    saveDemand();
                }
            });

        execB.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e) {
                    executeDemand();
                }
            });

        commentF.addKeyListener(new KeyAdapter()
            {
                @Override
                public void keyTyped(KeyEvent e)
                {
                    int i  = commentF.getText().length();
                    if (commentF.getText().length() > Constants.MAX_COMMENT_LENGTH)
                    {
                        commentF.setForeground(Constants.ERROR_COLOR);
                    }
                    else
                    {
                        commentF.setForeground(Constants.NORMAL_COLOR);
                    }
                }
            });

    }

    /**
     * Процедура, в результате которой в панели отображается подробная информация о заявке
     * @param demand объект заявки
     */
    public void showDemand(Demand demand, Admin admin)
    {
        try
        {
            this.demand = demand;
            this.themeF.setText(demand.getTheme());
            this.subjectF.setText(demand.getSubject());
            this.pcF.setText(demand.getPc());
            this.dateStartF.setText(demand.getTimeString());
            this.commentF.setText(demand.getComment());
            this.userF.setText(demand.getUser());
            setAdmin(admin);
            setStatus();

            //Дата выполнения заявки
            
            if (demand.getTimeExec() == 0)
            {
                this.dateEndF.setText("Не выполнена");
                this.execB.setEnabled(true);
                this.saveB.setEnabled(true);
            }
            else
            {
                this.dateEndF.setText(demand.getTimeExecString());
                this.execB.setEnabled(false);
                this.saveB.setEnabled(false);
            }

        } catch (Exception e) 
        {
            this.demand = null;
            this.themeF.setText("");
            this.subjectF.setText("");
            this.pcF.setText("");
            this.dateStartF.setText("");
            this.commentF.setText("");
            this.dateEndF.setText("");
            this.userF.setText("");
            statusCmb.setSelectedIndex(0);
        };
    }

    private void setStatus()
    {
        String status = demand.getStatus();

        if (status.equals("Не рассмотрена"))
            statusCmb.setSelectedIndex(0);
        else
            if (status.equals("В работе"))
                statusCmb.setSelectedIndex(1);
            else
                if (status.equals("Выполнена"))
                    statusCmb.setSelectedIndex(2);
                else
                    statusCmb.setSelectedIndex(3);
    }

    public void setIAdmin(Admin iAdmin)
    {
        this.iAdmin = iAdmin;
    }

    public JComboBox getAdminsList()
    {
        return this.adminCmb;
    }

    public void clearDemand()
    {
        this.demand = null;
        this.themeF.setText("");
        this.subjectF.setText("");
        this.pcF.setText("");
        this.dateStartF.setText("");
        this.commentF.setText("");
        this.dateEndF.setText("");
        this.userF.setText("");
        statusCmb.setSelectedIndex(0);
    }

    public void setTable(JTable table)
    {
        this.table = table;
    }

    /**
     * Процедура сохранения заявки после редактирования ее администратором.
     * На самом деле сохраняться будет только комментарий к заявке и назначенный администратор
     */
    private void saveDemand()
    {
        if ((demand != null) && (commentF.getForeground().equals(Constants.NORMAL_COLOR)))
        {
            int idDemand = demand.getId();
            AdminComboBoxModel acbm = (AdminComboBoxModel) adminCmb.getModel();
            int idAdmin = acbm.getAdmin(adminCmb.getSelectedIndex()).getId();
            String comment = commentF.getText();
            String status = statusCmb.getSelectedItem().toString();

            if ((iAdmin.isRoot() && status.equals("Заблокирована")) || !status.equals("Заблокирована"))
            {
                Actions.editDemand(idDemand, idAdmin, comment, status);
                try {
                    ldp.filterDemands();
                } catch (Exception ex) {
                    DesignTools.showMessage("Ошибка", "Не удалось обновить таблицу заявок.\nВозможно, отключен сервер, или неверные настройки\n"
                            + "ip адреса сервера и порта. Пожалуйста, проверьте их.", false);
                }
            }
            else
                DesignTools.showMessage("Ошибка", "Вы не можете блокировать заявки", false);
        }
        else
            DesignTools.showMessage("Ошибка", "Заявка не сохранена. \nЕсли в поле \"Комментарий\" цвет красного цвета, сократите его", false);
    }

    private void setAdmin(Admin admin)
    {
        AdminComboBoxModel acbm = (AdminComboBoxModel) adminCmb.getModel();
        if (admin != null)
        {            
            int idAdmin = acbm.getAdminPosition(admin);

            if (idAdmin != -1)
                adminCmb.setSelectedIndex(idAdmin);

            adminCmb.repaint();
        }
        else
           adminCmb.setSelectedIndex(acbm.getSize() - 1);
        adminCmb.repaint();
        
    }

    /**
     * Процедура отметки о выполнении заявки
     */
    private void executeDemand()
    {
        if ((demand != null) && (iAdmin != null))
        {
            Actions.executeDemand(demand.getId(), iAdmin.getId());
            try {
                //ldp.setTable(table);
                ldp.filterDemands();
            } catch (Exception ex) {
                DesignTools.showMessage("Ошибка", "Не удалось обновить таблицу заявок.\nВозможно, отключен сервер, или неверные настройки\n"
                        + "ip адреса сервера и порта. Пожалуйста, проверьте их.", false);
            }
        }
    }

    public void setLeftDemandPanel(LeftDemandPanel ldp)
    {
        this.ldp = ldp;
    }

}
